<template>
    <div class="user-chat-detail-container height-100-percent">
        <div class="header">
            {{userData["userInfo"]['username']}}
        </div>
        <div class="content chat-box-content">
            <div class="box custom-scrollbar" ref="chatBoxContent">
                <div class="loading-finish" v-if="loadFinish">
                    <span>加载完成</span>
                </div>
                <div :class="[currentUserId==item.fromUserId?'item flex':'item flex self flex-direction-row-reverse']"
                     v-for="(item,index) in userData.messageList"
                     :key="index">
                    <div class="avatar">
                        <el-icon size="14">
                            <User/>
                        </el-icon>
                    </div>
                    <div class="chat-content">
                        <div class="text">{{item.content}}</div>
                        <div class="time">
                            {{item.createdAt}}
                        </div>
                        <div v-if="currentUserId!=item.fromUserId" class="message-status">
                            <span class="is-read" v-if="item.isRead===1">已读</span>
                            <span class="no-read" v-else>未读</span>
                        </div>
                    </div>
                </div>
            </div>
            <span :class="[loading?'loading-icon show':'loading-icon']">
            <el-icon><Loading/></el-icon>
            </span>
        </div>
        <div class="form-container">
            <textarea v-model="content" class="custom-scrollbar none"/>
            <el-button class="btn" :loading="!connectStatus" @click="handleSendMessage" type="primary">
                {{connectStatus?'发送':'正在连接...'}}
            </el-button>
        </div>
    </div>
</template>

<script setup>
    import {ElMessage} from 'element-plus';
    import {User, Loading} from '@element-plus/icons-vue';
    import {onMounted, onBeforeUnmount, watch, getCurrentInstance, reactive, nextTick, ref, computed} from 'vue';
    import {useRoute} from 'vue-router';
    import {useStore} from 'vuex';

    const route = useRoute();
    const store = useStore();
    const chatBoxContent = ref();
    const {proxy} = getCurrentInstance();
    let currentUserId = route.params['id'];
    const connectStatus = computed(() => store.getters.getConnectStatus);
    let userData = reactive({
        userInfo: {},
        messageList: []
    });
    let content = '';
    let loading = ref(false);//是否正在加载
    let scrollTop = ref(10);//当前滚动距离
    let loadFinish = ref(false);//是否加载完成
    let isInit = true;//是否初始化

    //定义监听事件
    const sockets = {
        async messageList(data) {
            if (data.length < 20) {
                loadFinish.value = true;
            }
            data.reverse();
            userData.messageList = data;
            await scrollBottom();
            chatBoxContent.value.addEventListener('scroll', listenerScroll, true);
        },
        async nextMessageList(data) {
            data.reverse();
            if (data.length < 20) {
                loadFinish.value = true;
            }
            let oldHeight = chatBoxContent.value.scrollHeight;
            userData.messageList.unshift(...data);
            await nextTick(() => {
                chatBoxContent.value.scrollTo({
                    top: chatBoxContent.value.scrollHeight - oldHeight,
                    behavior: 'instant'
                });
                setTimeout(function () {
                    loading.value = false;
                }, 100)
            });
        },
        async userInfo(data) {
            userData.userInfo = data;
        },
        //成功将消息记录到数据库
        async successAddMessage(data) {
            if (data.code === 1) {
                //添加成功后将消息展示到消息列表
                const messageObj = {
                    ...data.data
                };
                userData.messageList.push(messageObj);
                content = '';
                await scrollBottom();
            } else {
                ElMessage({
                    showClose: false,
                    message: data.msg,
                    type: 'error',
                });
            }
        },
        //接收对方消息
        async acceptMessage(data) {
            if (data.fromUserId == currentUserId) {
                userData.messageList.push(data);
                //成功接收后通知对方消息已读
                proxy.$socket.io.emit('notifyAcceptSuccess', {
                    toUserId: data['fromUserId'],
                    messageId: data['id']
                });//发送消息
                await scrollBottom();
            } else {
                proxy.$socket.io.emit('getNewMessageCount');
                proxy.$socket.io.emit('getChatList');
            }

        },
        //消息已读
        messageIsRead() {
            for (let i = 0; i < userData.messageList.length; i++) {
                if (userData.messageList[i].isRead === 0) {
                    userData.messageList[i].isRead = 1;
                }
            }
        }
    };

    onMounted(async () => {
        isInit = true;
        loadFinish.value = false;
        await store.dispatch('handleCurrentChatId', currentUserId || 0);
        proxy.$socket.io.emit('getMessageList', currentUserId);//触发获取指定用户id的聊天列表
        proxy.$socket.io.emit('getUserInfo', currentUserId);//获取当前用户信息
        proxy.$addSockets(sockets, proxy);
    });

    onBeforeUnmount(async () => {
        proxy.$socket.io.emit('leaveChat');
        proxy.$removeSockets(sockets, proxy);
        chatBoxContent.value.removeEventListener('scroll', listenerScroll);
    });

    watch(() => route.params, async () => {
        isInit = true;
        loadFinish.value = false;
        chatBoxContent.value.removeEventListener('scroll', listenerScroll);
        currentUserId = route.params['id'];
        if (currentUserId) {
            proxy.$socket.io.emit('getMessageList', currentUserId);//触发获取指定用户id的聊天列表
            proxy.$socket.io.emit('getUserInfo', currentUserId);//获取当前用户信息
            await store.dispatch('handleCurrentChatId', route.params['id'] || 0);
        }
    });

    //监听socket连接状态变化
    watch(() => store.getters.getConnectStatus, (data) => {
        if (data) {
            proxy.$socket.io.emit('isChat');
        }
    });

    //发送消息
    const handleSendMessage = async () => {
        if (connectStatus.value) {
            if (content.length <= 0) {
                ElMessage({
                    showClose: false,
                    message: '消息不能为空',
                    type: 'warning',
                });
                return;
            }
            proxy.$socket.io.emit('sendMessage', {toUserId: currentUserId, content});//发送消息
        }
    };

    //聊天内容框滚动到底部
    const scrollBottom = async () => {
        await nextTick(() => {
            chatBoxContent.value.scrollTo({
                top: chatBoxContent.value.scrollHeight,
                behavior: isInit ? 'instant' : 'smooth'
            });
            isInit = false;
        });
    };

    //监听滚动事件
    const listenerScroll = (e) => {
        if (loadFinish.value) {
            return;
        }
        if (e.target.scrollTop < 10 && loading.value === false) {
            if (scrollTop.value > e.target.scrollTop) {
                loading.value = true;
                proxy.$socket.io.emit('getNextMessageList', currentUserId, userData.messageList.length);//触发获取指定用户id的聊天列表
            }
        }
        scrollTop.value = e.target.scrollTop;
    }

</script>

<style lang="less" scoped>
    @keyframes loading {
        from {
            -webkit-transform: rotate(0);
            -moz-transform: rotate(0);
            -ms-transform: rotate(0);
            -o-transform: rotate(0);
            transform: rotate(0);
        }
        to {
            -webkit-transform: rotate(360deg);
            -moz-transform: rotate(360deg);
            -ms-transform: rotate(360deg);
            -o-transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }

    .user-chat-detail-container {
        .header {
            height: 50px;
            line-height: 50px;
            border-bottom: 1px solid #C0C4CC;
            background: #fff;
        }

        .content {
            height: calc(100% - 151px);
            overflow: hidden;
            position: relative;

            .box {
                height: 100%;
                background: #F2F6FC;
                padding: 15px;
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                box-sizing: border-box;
                overflow: auto;

                .loading-finish {
                    text-align: center;
                    font-size: 12px;
                    position: relative;
                    height: 1px;
                    background: #dcdfe6;
                    margin: 10px 0;

                    span {
                        display: inline-block;
                        background: #F2F6FC;
                        width: 80px;
                        position: absolute;
                        height: 20px;
                        line-height: 20px;
                        top: 50%;
                        margin-top: -10px;
                        left: 50%;
                        margin-left: -40px;
                        color: #999;
                    }
                }

                .item {
                    margin: 20px 0;

                    .avatar {
                        width: 36px;
                        height: 36px;
                        line-height: 40px;
                        -webkit-border-radius: 50%;
                        -moz-border-radius: 50%;
                        border-radius: 50%;
                        border: 1px solid #ddd;
                    }

                    .chat-content {
                        position: relative;
                        background: #ddd;
                        font-size: 12px;
                        padding: 10px;
                        -webkit-border-radius: 3px;
                        -moz-border-radius: 3px;
                        border-radius: 3px;
                        border-bottom-right-radius: 20px;
                        margin-left: 10px;
                        max-width: 250px;
                        text-align: left;

                        &:hover {
                            .time {
                                opacity: 1;
                            }
                        }

                        .time {
                            position: absolute;
                            left: 0;
                            min-width: 150px;
                            top: 105%;
                            font-size: 12px;
                            color: #999;
                            opacity: 0;
                            -webkit-transition: opacity 0.3s linear 0s;
                            -moz-transition: opacity 0.3s linear 0s;
                            -ms-transition: opacity 0.3s linear 0s;
                            -o-transition: opacity 0.3s linear 0s;
                            transition: opacity 0.3s linear 0s;
                        }
                    }

                    &.self {
                        .avatar {
                            background: #ef8d81;
                            color: #fff;
                            border: 1px solid #ef8d81;
                        }

                        .chat-content {
                            -webkit-border-radius: 3px;
                            -moz-border-radius: 3px;
                            border-radius: 3px;
                            border-bottom-left-radius: 20px;
                            border-bottom-right-radius: 3px;
                            margin-left: unset;
                            margin-right: 10px;
                            background: #5d9afe;
                            color: #fff;

                            .time {
                                left: unset;
                                right: 0;
                                text-align: right;
                            }

                            .message-status {
                                position: absolute;
                                font-size: 12px;
                                right: 100%;
                                top: 50%;
                                color: #000;
                                width: 40px;
                                text-align: center;
                                -webkit-transform: scale(0.9);
                                -moz-transform: scale(0.9);
                                -ms-transform: scale(0.9);
                                -o-transform: scale(0.9);
                                transform: scale(0.9);
                            }
                        }
                    }
                }
            }

            .loading-icon {
                -webkit-animation: loading 2s linear 0s infinite;
                -o-animation: loading 2s linear 0s infinite;
                animation: loading 2s linear 0s infinite;
                width: 16px;
                height: 16px;
                display: inline-block;
                position: absolute;
                -webkit-transition: top 0.3s linear 0s;
                -moz-transition: top 0.3s linear 0s;
                -ms-transition: top 0.3s linear 0s;
                -o-transition: top 0.3s linear 0s;
                transition: top 0.3s linear 0s;
                top: -50px;

                &.show {
                    top: 10px;
                }
            }
        }

        .form-container {
            height: 100px;
            position: relative;

            input {
                border: none;
                height: 100%;
            }

            .btn {
                position: absolute;
                bottom: 10px;
                right: 20px;
            }
        }
    }
</style>
<style>
    textarea {
        height: 100% !important;
        outline: none;
        border: none;
        width: 100%;
        resize: none;
        padding: 10px;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }
</style>